package com.financial.business.yspay.service.impl;

import com.financial.business.yspay.connector.YsBusinessFeign;
import com.financial.business.yspay.constants.FinancialSplitYsEnumConstants;
import com.financial.business.yspay.dao.FinancialSplitYsDao;
import com.financial.business.yspay.domain.FinancialSplitYsDO;
import com.financial.business.yspay.dto.YsSplitDTO;
import com.financial.business.yspay.dto.split.YsDivListDTO;
import com.financial.business.yspay.dto.split.YsSpiltDTO;
import com.financial.business.yspay.service.FinancialSplitYsService;
import com.financial.business.yspay.utils.JsonUtils;
import com.financial.business.yspay.utils.ValidateUtils;
import com.financial.business.yspay.utils.apiresult.ApiResult;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;


@Service
public class FinancialSplitYsServiceImpl implements FinancialSplitYsService {
    public static final Logger logger = LoggerFactory.getLogger(FinancialSplitYsServiceImpl.class);

    @Autowired
    private FinancialSplitYsDao financialSplitYsDao;

    @Autowired
    private YsBusinessFeign ysBusinessFeign;

    @Override
    public FinancialSplitYsDO get(Integer id) {
        return financialSplitYsDao.get(id);
    }

    @Override
    public List<FinancialSplitYsDO> list(Map<String, Object> map) {
        return financialSplitYsDao.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        return financialSplitYsDao.count(map);
    }

    @Override
    public int save(FinancialSplitYsDO financialSplitYs) {
        return financialSplitYsDao.save(financialSplitYs);
    }

    @Override
    public int update(FinancialSplitYsDO financialSplitYs) {
        return financialSplitYsDao.update(financialSplitYs);
    }

    /**
     * 银盛一清分账
     *
     * @param requestParam
     * @return
     */
    @Override
    public ApiResult ysSplit(String requestParam) {
        logger.info("FinancialSplitYsServiceImpl.ysSplit()------监听到平台内部分账完成json为：" + requestParam);
        YsSplitDTO ysSplitDTO = JsonUtils.convertBean(requestParam, YsSplitDTO.class);
        Map<String, Object> mapParams = JsonUtils.jsonToMap(requestParam);
        Object tempParams = mapParams.get("total_amount");
        /*分账金额*/
        String totalAmountStr = tempParams == null ? null : tempParams.toString();
        /*三方支付专用交易单号*/
        tempParams = mapParams.get("out_trade_no");
        String outTradeNo = tempParams == null ? null : tempParams.toString();
        /*对接平台商户号*/
        tempParams = mapParams.get("store_no");
        String storeNo = tempParams == null ? null : tempParams.toString();
        /*分账手续费*/
        tempParams = mapParams.get("split_fee");
        String splitFee = tempParams == null ? null : tempParams.toString();
        /*主商户号（原交易收款方）*/
        tempParams = mapParams.get("payee_usercode");
        String payeeUsercode = tempParams == null ? null : tempParams.toString();
        /*分账子商户号*/
        tempParams = mapParams.get("division_mer_usercode");
        String divisionMerUsercode = tempParams == null ? null : tempParams.toString();
        /*回执地址*/
        tempParams = mapParams.get("notify_url");
        String notifyUrl = tempParams == null ? null : tempParams.toString();
        /*子商户分账金额*/
        tempParams = mapParams.get("div_amount");
        String divAmountStr = tempParams == null ? null : tempParams.toString();
        /*积分金额*/
        tempParams = mapParams.get("virtual_amount");
        String virtualAmountStr = tempParams == null ? null : tempParams.toString();
        /*银盛平台开设平台金额*/
        tempParams = mapParams.get("planform_amount");
        String planformAmountStr = tempParams == null ? null : tempParams.toString();
        /*分账类型*/
        tempParams = mapParams.get("split_type");
        String splitType = tempParams == null ? null : tempParams.toString();
        /*在银盛开设的营销账户*/
        tempParams = mapParams.get("virtual_code");
        String virtualCode = tempParams == null ? null : tempParams.toString();
        /*在银盛开设的平台账户*/
        tempParams = mapParams.get("planform_code");
        String planformCode = tempParams == null ? null : tempParams.toString();
        /*对接平台编码*/
        tempParams = mapParams.get("platform_no");
        String platformNo = tempParams == null ? null : tempParams.toString();
        if (StringUtils.isBlank(totalAmountStr) || StringUtils.isBlank(outTradeNo)
                || StringUtils.isBlank(storeNo) || StringUtils.isBlank(splitFee)
                || StringUtils.isBlank(payeeUsercode) || StringUtils.isBlank(storeNo)
                || StringUtils.isBlank(divisionMerUsercode) || StringUtils.isBlank(notifyUrl)
                || StringUtils.isBlank(divAmountStr) || StringUtils.isBlank(splitType)
                || StringUtils.isBlank(platformNo)) {
            return ApiResult.failure(ValidateUtils.validateProperty(ysSplitDTO));
        }
        /*原订单是否参与分账01：是，02否*/
        String isDivistion = FinancialSplitYsEnumConstants.ENUM_IS_DIVISTION;
        /*分账模式01 ：比例，02：金额*/
        String divisionMode = FinancialSplitYsEnumConstants.ENUM_MODE_CASH;
        /*是否重新分账*/
        String isAgainDivision = FinancialSplitYsEnumConstants.ENUM_DIVISIONAGAIN_YES;
        /*对分账所有的金额进行精确度设置，保留两位小数*/
        /*分账总金额*/
        BigDecimal totalAmount = new BigDecimal(totalAmountStr).setScale(2, RoundingMode.HALF_UP);
        /*子商户分账金额*/
        BigDecimal divAmount = new BigDecimal(divAmountStr).setScale(2, RoundingMode.HALF_UP);
        /*积分账户金额*/
        BigDecimal virtualAmount = new BigDecimal(virtualAmountStr).setScale(2, RoundingMode.HALF_UP);
        /*平台账户金额*/
        BigDecimal planformAmount = new BigDecimal(planformAmountStr).setScale(2, RoundingMode.HALF_UP);
        /*分账商户*/
        YsDivListDTO merUserCodeDTO = new YsDivListDTO();
        merUserCodeDTO.setDivision_mer_usercode(divisionMerUsercode);
        merUserCodeDTO.setDiv_amount(divAmount);
        merUserCodeDTO.setIs_chargeFee(FinancialSplitYsEnumConstants.ENUM_YSE_CHARGEFEE);
        /*银盛平台开设积分分账*/
        YsDivListDTO virtualDTO = new YsDivListDTO();
        virtualDTO.setDivision_mer_usercode(virtualCode);
        virtualDTO.setDiv_amount(virtualAmount);
        virtualDTO.setIs_chargeFee(FinancialSplitYsEnumConstants.ENUM_NO_CHARGEFEE);
        /*银盛平台主商户分账*/
        YsDivListDTO planformDTO = new YsDivListDTO();
        planformDTO.setDivision_mer_usercode(planformCode);
        planformDTO.setDiv_amount(planformAmount);
        planformDTO.setIs_chargeFee(FinancialSplitYsEnumConstants.ENUM_NO_CHARGEFEE);
        /*判断商户分账*/
        /*平台无抽成*/
        List<YsDivListDTO> divList = new ArrayList<YsDivListDTO>();
        if (planformAmount.compareTo(BigDecimal.ZERO) == 0.00) {
            //平台无抽成，积分无抽成
            if (virtualAmount.compareTo(BigDecimal.ZERO) == 0.00) {
                divList.add(merUserCodeDTO);
            } else {
                //平台无抽成，积分有抽成
                divList.add(merUserCodeDTO);
                divList.add(virtualDTO);
            }
        } else {
            //平台有抽成，积分无抽成
            if (virtualAmount.compareTo(BigDecimal.ZERO) == 0.00) {
                divList.add(merUserCodeDTO);
                divList.add(planformDTO);
            } else {
                //平台、积分都有抽成
                divList.add(merUserCodeDTO);
                divList.add(planformDTO);
                divList.add(virtualDTO);
            }
        }
        ApiResult apiResult = null;
        try {
            /*开始组装调用银盛分账服务参数信息*/
            YsSpiltDTO splitDTO = new YsSpiltDTO();
            splitDTO.setOut_trade_no(outTradeNo);
            splitDTO.setPayee_usercode(payeeUsercode);
            splitDTO.setDivision_mode(divisionMode);
            splitDTO.setTotal_amount(totalAmount);
            splitDTO.setIs_divistion(isDivistion);
            splitDTO.setDiv_list(divList);
            splitDTO.setIs_again_division(isAgainDivision);
            String ysSplitJSON = JsonUtils.objectToJson(splitDTO);
            logger.info("FinancialSplitYsServiceImpl.ysSplit()------拼接请求银盛数据格式：ysSplitReceiptJSON：" + ysSplitJSON);
            /*保存银盛分账记录初始化表*/
            FinancialSplitYsDO financialSplitYsDO = new FinancialSplitYsDO();
            /*通过订单号查询该订单历史记录*/
            FinancialSplitYsDO financialSplitYsDOInfo= financialSplitYsDao.getOne(outTradeNo);
            logger.info("FinancialSplitYsServiceImpl.ysSplit()------通过订单号查询历史分账信息,订单号:{}",outTradeNo);
            int res =0;
            if(financialSplitYsDOInfo!=null){
                logger.info("FinancialSplitYsServiceImpl.ysSplit()------通过订单号查询历史分账信息存在,执行更新操作");
                Map<String,Object> dataParams=new HashMap<>();
                dataParams.put("outTradeNo",outTradeNo);
                dataParams.put("gmtModified",new Date());
                dataParams.put("returnMessage",ysSplitJSON);
                dataParams.put("state",FinancialSplitYsEnumConstants.ENUM_STATE_WAIT);
                /*通过订单号查询历史分账订单状态*/
                String state=financialSplitYsDOInfo.getState();
                if(state.equals("0")){
                    logger.info("FinancialSplitYsServiceImpl.ysSplit()------通过订单号查询历史分账状态成功");
                    return ApiResult.success("该订单历史分账状态成功");
                }else{
                    logger.info("FinancialSplitYsServiceImpl.ysSplit()------通过订单号查询历史分账状态不成功-未分账或分账失败");
                    res=financialSplitYsDao.updateInfo(dataParams);
                }
            }else{
                logger.info("FinancialSplitYsServiceImpl.ysSplit()------通过订单号查询历史分账信息不存在,执行创建保存操作");
                financialSplitYsDO.setGmtCreate(new Date());
                financialSplitYsDO.setIsDelete(FinancialSplitYsEnumConstants.ENUM_ISDELETE_UNDEL);
                financialSplitYsDO.setOutTradeNo(outTradeNo);
                financialSplitYsDO.setResqContent(requestParam);
                financialSplitYsDO.setSplitFee(new BigDecimal(splitFee));
                financialSplitYsDO.setState(FinancialSplitYsEnumConstants.ENUM_STATE_WAIT);
                financialSplitYsDO.setPlatformNo(platformNo);
                financialSplitYsDO.setStoreNo(storeNo);
                financialSplitYsDO.setReturnMessage(ysSplitJSON);
                res = financialSplitYsDao.save(financialSplitYsDO);
            }
            if (res > 0) {
                /*请求银盛分账*/
                apiResult = ysBusinessFeign.ysSplit(ysSplitJSON);
                /*根据返回信息进行状态判断*/
                Integer payCode = apiResult.getCode();
                String apiResultMsg = (String) apiResult.getResult();
                Map<String, Object> condMap = new HashMap<>();
                condMap.put("outTradeNo", outTradeNo);
                condMap.put("returnMessage", apiResultMsg);
                if (payCode == FinancialSplitYsEnumConstants.ENUM_RETURNCODE_SUC && (apiResultMsg != null && apiResultMsg != "")) {
                    /*成功状态*/
                    condMap.put("state", FinancialSplitYsEnumConstants.ENUM_STATE_SUC);
                    int updateInfoState = financialSplitYsDao.updateInfo(condMap);
                    if (updateInfoState > 0) {
                        return ApiResult.success(apiResultMsg);
                    } else {
                        return ApiResult.failure(apiResult);
                    }
                } else {
                    condMap.put("state", FinancialSplitYsEnumConstants.ENUM_STATE_FAIL);
                    financialSplitYsDao.updateInfo(condMap);
                    return ApiResult.failure(apiResult);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return apiResult;
    }

    /**
     * 通过map查询一条分账记录
     *
     * @param condMap
     * @return
     */
    @Override
    public String query(Map<String, Object> condMap) {

        return financialSplitYsDao.query(condMap);
    }
}
